package com.wondertek.onvif.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 设备配置管理器
 * 管理不同设备的特定配置和重试策略
 */
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "onvif.device")
public class DeviceConfigManager {
    
    private static final Logger log = LoggerFactory.getLogger(DeviceConfigManager.class);
    
    /**
     * 默认连接超时时间（毫秒）
     */
    private int defaultConnectionTimeout = 5000;
    
    /**
     * 默认读取超时时间（毫秒）
     */
    private int defaultReadTimeout = 10000;
    
    /**
     * 默认重试次数
     */
    private int defaultRetryCount = 3;
    
    /**
     * 默认重试间隔（毫秒）
     */
    private int defaultRetryInterval = 1000;
    
    /**
     * 设备特定配置
     * key: 设备型号或厂商名称
     * value: 设备配置
     */
    private Map<String, DeviceConfig> deviceConfigs = new HashMap<>();
    
    /**
     * 根据设备类型获取配置
     * 
     * @param deviceType 设备类型（如：hikvision、dahua、uniview、axis等）
     * @return 设备配置
     */
    public DeviceConfig getDeviceConfig(String deviceType) {
        if (deviceType == null || deviceType.trim().isEmpty()) {
            log.debug("设备类型为空，使用默认配置");
            return createDefaultConfig();
        }
        
        DeviceConfig config = deviceConfigs.get(deviceType.toLowerCase());
        
        if (config == null) {
            log.debug("未找到设备类型 {} 的配置，使用默认配置", deviceType);
            config = createDefaultConfig();
        } else {
            log.debug("获取设备配置: {}, 使用配置: {}", deviceType, config);
        }
        
        return config;
    }
    
    /**
     * 根据设备信息获取配置
     * 
     * @param manufacturer 厂商
     * @param model 型号
     * @return 设备配置
     */
    public DeviceConfig getDeviceConfig(String manufacturer, String model) {
        // 优先匹配具体型号
        String fullKey = manufacturer + "-" + model;
        DeviceConfig config = deviceConfigs.get(fullKey.toLowerCase());
        
        if (config == null) {
            // 匹配厂商
            config = deviceConfigs.get(manufacturer.toLowerCase());
        }
        
        if (config == null) {
            // 使用默认配置
            config = createDefaultConfig();
        }
        
        log.debug("获取设备配置: {} - {}, 使用配置: {}", manufacturer, model, config);
        return config;
    }
    
    /**
     * 创建默认配置
     * 
     * @return 默认设备配置
     */
    public DeviceConfig createDefaultConfig() {
        DeviceConfig config = new DeviceConfig();
        config.setConnectionTimeout(defaultConnectionTimeout);
        config.setReadTimeout(defaultReadTimeout);
        config.setRetryCount(defaultRetryCount);
        config.setRetryInterval(defaultRetryInterval);
        config.setPreferredAuthMethods(new String[]{"Basic", "Digest", "None"});
        config.setUseHeadForDigest(true);
        config.setFallbackToGet(true);
        return config;
    }
    
    /**
     * 设备配置类
     */
    public static class DeviceConfig {
        /**
         * 连接超时时间（毫秒）
         */
        private int connectionTimeout = 5000;
        
        /**
         * 读取超时时间（毫秒）
         */
        private int readTimeout = 10000;
        
        /**
         * 重试次数
         */
        private int retryCount = 3;
        
        /**
         * 重试间隔（毫秒）
         */
        private int retryInterval = 1000;
        
        /**
         * 首选认证方法（按优先级排序）
         */
        private String[] preferredAuthMethods = {"Basic", "Digest", "None"};
        
        /**
         * Digest认证是否使用HEAD请求探测
         */
        private boolean useHeadForDigest = true;
        
        /**
         * HEAD请求失败时是否回退到GET请求
         */
        private boolean fallbackToGet = true;
        
        /**
         * 是否启用详细日志
         */
        private boolean enableVerboseLogging = false;
        
        /**
         * 自定义请求头
         */
        private Map<String, String> customHeaders = new HashMap<>();
        
        // Getter and Setter methods
        public int getConnectionTimeout() {
            return connectionTimeout;
        }
        
        public void setConnectionTimeout(int connectionTimeout) {
            this.connectionTimeout = connectionTimeout;
        }
        
        public int getReadTimeout() {
            return readTimeout;
        }
        
        public void setReadTimeout(int readTimeout) {
            this.readTimeout = readTimeout;
        }
        
        public int getRetryCount() {
            return retryCount;
        }
        
        public void setRetryCount(int retryCount) {
            this.retryCount = retryCount;
        }
        
        public int getRetryInterval() {
            return retryInterval;
        }
        
        public void setRetryInterval(int retryInterval) {
            this.retryInterval = retryInterval;
        }
        
        public String[] getPreferredAuthMethods() {
            return preferredAuthMethods;
        }
        
        public void setPreferredAuthMethods(String[] preferredAuthMethods) {
            this.preferredAuthMethods = preferredAuthMethods;
        }
        
        public boolean isUseHeadForDigest() {
            return useHeadForDigest;
        }
        
        public void setUseHeadForDigest(boolean useHeadForDigest) {
            this.useHeadForDigest = useHeadForDigest;
        }
        
        public boolean isFallbackToGet() {
            return fallbackToGet;
        }
        
        public void setFallbackToGet(boolean fallbackToGet) {
            this.fallbackToGet = fallbackToGet;
        }
        
        public boolean isEnableVerboseLogging() {
            return enableVerboseLogging;
        }
        
        public void setEnableVerboseLogging(boolean enableVerboseLogging) {
            this.enableVerboseLogging = enableVerboseLogging;
        }
        
        public Map<String, String> getCustomHeaders() {
            return customHeaders;
        }
        
        public void setCustomHeaders(Map<String, String> customHeaders) {
            this.customHeaders = customHeaders;
        }
    }
}